(function () {
    // 获取节点
    function getNode(className, element) {
        var element = element || document;
        if(typeof className !== 'string') className = '[data-flag=' + className.active.name + ']';
        return element.querySelector(className);
    }
    // 获取节点集合
    function getNodes(className, element) {
        var element = element || document,
            transform = Array.prototype.slice,
            nodes = [];
        if(element.length!== undefined){
            element = transform.apply(element);
            element.forEach(function (el) {
                var els = el.querySelectorAll(className) || [];
                els = transform.apply(els);
                nodes.push.apply(nodes, els);
            })
            return nodes;
        }
        nodes = element.querySelectorAll(className) || [];
        return transform.apply(nodes);
    }
    // 更新节点flag
    function updateFlag(oldNode, node) {
        oldNode.removeAttribute('active-flag');
        node.setAttribute('active-flag', 'true');
        // 使用原生select标签时，火狐游览器无焦点选中的蓝色边框，那就主动加一个
        if (window.navigator.userAgent.indexOf('Firefox') >= 0) {
            oldNode.style.border = '';
            node.style.border = '1px solid #75ADFF';
        }
    }
    /**
     * Table Cell Switch by keys
     * TabelCellSWitch构造函数
     * @param queryStr 类CSS选择字符串（必传）
     * @param vm Vue组件实例引用 （可选）
     * @returns Object:TCSwitch
     */
    function TCSwitch(query, vm) {
        this._initObjInfo(query, vm);
        this._initDomInfo();
        this._createFlag();
        this._bindEvent();
        this._setActive(0, 0);
    }
    TCSwitch.prototype = {
        constructor: TCSwitch,
        // 初始化实例信息
        _initObjInfo: function (query, vm) {
            this.container = getNode(query);
            this.clickHandle = null;
            this.keydownHandle = null;
            this.isSwitch = true;
            this.isActive = false;
            // 单页项目，用于区分组件页面
            if (vm) {
                this.page = vm;
                this.pageName = page.$route.name;
            }
        },
        // 初始化dom信息
        _initDomInfo: function () {
            var tbody = getNode('tbody', this.container);
            this.tbody = tbody ? tbody : this.container;
            this.tr = getNodes('tr', this.tbody);
            if (this.tr.length > 0) {
                this.ylen = this.tr.length;
                this.xlen = getNodes('input,select', this.tr).length / this.ylen;
            }
        },
        // 创建标记
        _createFlag: function () {
            this.tr.forEach(function (dom, i) {
                var nodes = getNodes('input,select', dom);
                nodes.forEach(function (dom, j) {
                    dom.setAttribute('data-flag', 'x' + j + '-' + 'y' + i);
                })
            })
        },
        // 绑定事件
        _bindEvent: function () {
            this.keydownHandle = function (e) {
                var oldNode, node,
                    keyCode = e.keyCode,
                    that = this;
                // 是否为实例化的页面（单页项目，用于区分组件页面）
                if(this.page && this.page.$route.name !== this.pageName) return;
                // 按键操作是否为上下左右
                if (String(keyCode).search(/37|38|39|40/) >= 0 && this.isSwitch) {
                    // 暂时关闭切换
                    this.isSwitch = false;
                    // 获取离开节点
                    oldNode = getNode(this);
                    // 切换Active
                    this._switchActive(keyCode);
                    // 获取新节点
                    node = getNode(this);
                    // 更新dom标记
                    updateFlag(oldNode, node);
                    // 新节点获取焦点
                    node.focus();
                    // 如果为input标签，增加select选中效果
                    if (node.nodeName == 'INPUT') {
                        setTimeout(function () {
                            node.select();
                            that.isSwitch = true;
                        }, 0);
                    } else {
                        this.isSwitch = true;
                    }
                    // 阻止默认行为
                    e.preventDefault();
                }
            }
            this.clickHandle = function (e) {
                var node = e.target,
                    oldNode = getNode(this),
                    nodeName = node.nodeName;
                if (nodeName == 'INPUT' || nodeName == 'SELECT') {
                    // 更新active对象
                    this._updateActive(node);
                    // 更新dom标记
                    updateFlag(oldNode, node);
                    // 获取焦点
                    node.focus();
                    // 如果为input标签，增加select选中效果
                    if (nodeName == 'INPUT') {
                        setTimeout(function(){
                            node.select();
                        }, 100)
                    }
                    this.isActive = true;
                    this.isSwitch = true;
                }
            };
            document.addEventListener('keydown', this.keydownHandle.bind(this));
            this.tbody.addEventListener('mousedown', this.clickHandle.bind(this));
        },
        // 按键切位
        _switchActive(keyCode){
            var x = this.active.x, 
                y = this.active.y;
            if(this.isActive){
                // 上
                if (keyCode == 38 && y > 0) y--;
                // 下
                if (keyCode == 40 && y < this.ylen - 1) y++;
                // 左
                if (keyCode == 37 && x > 0) x--;
                // 右
                if (keyCode == 39 && x < this.xlen - 1) x++;
                // 更新active对象
                this._setActive(x, y);
            } else {
                this.isActive = true;
            }
        },
        // 更新Active
        _updateActive(node) {
            var name = node.getAttribute('data-flag');
            var piont = name.match(/x(\d+)-y(\d+)/);
            this._setActive(piont[1], piont[2]);
        },
        // 设置Active
        _setActive(x, y) {
            this.active = {
                x: x,
                y: y,
                name: 'x' + x + '-' + 'y' + y
            }
            console.log('that.active = ' + this.active.name);
        },
        /**
         * 更新实例状态
         * @param isReset 是否重置光标位置 true | false ，如果传ture 光标会重新聚焦在 第一行第一列上
         */
        update: function (isReset) {
            if(isReset) this._setActive(0, 0);
            this.isfirst = !!isReset;
            this.isSwitch = true;
            this._initDomInfo();
            this._createFlag();
            var node = getNode('[active-flag]');
            if (node) this._updateActive(node);
        },
        /**
         * 销毁实例
         */
        destroy: function () {
            document.removeEventListener('keydown', this.keydownHandle);
            this.tbody.removeEventListener('mousedown', this.clickHandle);
            for (var i in this) {
                if (this.hasOwnProperty(i)) {
                    this[i] = null;
                }
            }
            console.log('销毁cut实例');
        }
    }
    window.TCSwitch = TCSwitch;
}())